import numpy as np

class SemiMarkovACController:
    def __init__(self, on_rate, off_rate, lock_time_seconds=180.0, execution_period=2.0):
        """
        on_rate: 由ON状态跳转到OFF锁定状态的迁移率 (1/s)
        off_rate: 由OFF状态跳转到ON锁定状态的迁移率 (1/s)
        lock_time_seconds: 锁定状态保持的时间 (s)
        execution_period: 控制周期 (s)，例如2秒
        """
        self.on_rate = on_rate
        self.off_rate = off_rate
        self.lock_time_steps = int(lock_time_seconds / execution_period)
        self.execution_period = execution_period
        self.state = 'OFF'  # 初始状态
        self.lock_timer = 0

    def step(self):
        """
        执行一次状态更新
        """
        if self.state == 'ON':
            # 开启状态 → 关闭锁定
            if np.random.rand() < self.on_rate * self.execution_period:
                self.state = 'OFF_LOCKED'
                self.lock_timer = self.lock_time_steps

        elif self.state == 'OFF_LOCKED':
            # 关闭锁定状态 → 关闭
            self.lock_timer -= 1
            if self.lock_timer <= 0:
                self.state = 'OFF'

        elif self.state == 'OFF':
            # 关闭状态 → 开启锁定
            if np.random.rand() < self.off_rate * self.execution_period:
                self.state = 'ON_LOCKED'
                self.lock_timer = self.lock_time_steps

        elif self.state == 'ON_LOCKED':
            # 开启锁定状态 → 开启
            self.lock_timer -= 1
            if self.lock_timer <= 0:
                self.state = 'ON'

        return self.state

    def reset(self, initial_state='OFF'):
        self.state = initial_state
        self.lock_timer = 0

if __name__ == '__main__':
    # 创建一个半马尔科夫空调控制器实例
    controller = SemiMarkovACController(
        on_rate=0.001,  # 迁移率 1/秒
        off_rate=0.001,
        lock_time_seconds=300,
        execution_period=2.0
    )

    # 记录状态变化
    states = []
    for _ in range(3600):  # 2秒步长，模拟2小时
        state = controller.step()
        states.append(state)

    # 可视化
    import matplotlib.pyplot as plt

    state_map = {'OFF': 0, 'OFF_LOCKED': 1, 'ON_LOCKED': 2, 'ON': 3}
    numeric_states = [state_map[s] for s in states]
    plt.plot(numeric_states)
    plt.yticks([0, 1, 2, 3], ['OFF', 'OFF_LOCKED', 'ON_LOCKED', 'ON'])
    plt.xlabel('Steps (2 seconds per step)')
    plt.ylabel('State')
    plt.title('AC State Transition Over Time')
    plt.grid(True)
    plt.show()


